{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 2.4 Runner类介绍\n",
    "\n",
    "通过上面的实践，我们可以看到，在一个任务上应用机器学习方法的流程基本上包括：数据集构建、模型构建、损失函数定义、优化器、模型训练、模型评价、模型预测等环节。\n",
    "\n",
    "为了更方便地将上述环节规范化，我们将机器学习模型的基本要素封装成一个**Runner**类。除上述提到的要素外，再加上模型保存、模型加载等功能。\n",
    "\n",
    "**Runner**类的成员函数定义如下：\n",
    "* \\_\\_init\\_\\_函数：实例化**Runner**类时默认调用，需要传入模型、损失函数、优化器和评价指标等；\n",
    "* train函数：完成模型训练，指定模型训练需要的训练集和验证集；\n",
    "* evaluate函数：通过对训练好的模型进行评价，在验证集或测试集上查看模型训练效果；\n",
    "* predict函数：选取一条数据对训练好的模型进行预测；\n",
    "* save\\_model函数：模型在训练过程和训练结束后需要进行保存；\n",
    "* load\\_model函数：调用加载之前保存的模型。\n",
    "\n",
    "`Runner`类的框架定义如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "class Runner(object):\n",
    "    def __init__(self, model, optimizer, loss_fn, metric):\n",
    "        self.model = model         # 模型\n",
    "        self.optimizer = optimizer # 优化器\n",
    "        self.loss_fn = loss_fn     # 损失函数   \n",
    "        self.metric = metric       # 评估指标\n",
    "\n",
    "    # 模型训练\n",
    "    def train(self, train_dataset, dev_dataset=None, **kwargs):\n",
    "        pass\n",
    "\n",
    "    # 模型评价\n",
    "    def evaluate(self, data_set, **kwargs):\n",
    "        pass\n",
    "\n",
    "    # 模型预测\n",
    "    def predict(self, x, **kwargs):\n",
    "        pass\n",
    "\n",
    "    # 模型保存\n",
    "    def save_model(self, save_path):\n",
    "        pass\n",
    "\n",
    "    # 模型加载\n",
    "    def load_model(self, model_path):\n",
    "        pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "**Runner**类的流程如**图2.8**所示，可以分为 4 个阶段：\n",
    "1. 初始化阶段：传入模型、损失函数、优化器和评价指标。\n",
    "1. 模型训练阶段：基于训练集调用`train()`函数训练模型，基于验证集通过`evaluate()`函数验证模型。通过`save_model()`函数保存模型。\n",
    "1. 模型评价阶段：基于测试集通过`evaluate()`函数得到指标性能。\n",
    "1. 模型预测阶段：给定样本，通过`predict()`函数得到该样本标签。\n",
    "\n",
    "<center><img src=\"https://ai-studio-static-online.cdn.bcebos.com/fdb656daadb349a78560fa464b0de5fa5d63423fc2234adfac48e6ff020a6d60\" width=700 ></img></center>\n",
    "\n",
    "<center>图2.8 Runner类</center>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 2.5 基于线性回归的波士顿房价预测  \n",
    "\n",
    "在本节中，我们使用线性回归来对马萨诸塞州波士顿郊区的房屋进行预测。实验流程主要包含如下5个步骤：\n",
    "* 数据处理：包括数据清洗（缺失值和异常值处理）、数据集划分，以便数据可以被模型正常读取，并具有良好的泛化性;\n",
    "* 模型构建：定义线性回归模型类；\n",
    "* 训练配置:训练相关的一些配置，如：优化算法、评价指标等；\n",
    "* 组装训练框架Runner:`Runner`用于管理模型训练和测试过程；\n",
    "* 模型训练和测试:利用`Runner`进行模型训练和测试。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 2.5.1 数据处理\n",
    "\n",
    "### 2.5.1.1 数据集介绍\n",
    "\n",
    "本实验使用波士顿房价预测数据集，共506条样本数据，每条样本包含了12种可能影响房价的因素和该类房屋价格的中位数，各字段含义如**表2.1**所示： \n",
    "\n",
    "<center>\n",
    "  \n",
    "| 字段名   | 类型 | 含义  |\n",
    "| -------- | -------- | -------- | \n",
    "| CRIM\t| float | 该镇的人均犯罪率 |\n",
    "| ZN\t| float |占地面积超过25,000平方呎的住宅用地比例|\n",
    "| INDUS\t| float |非零售商业用地比例|\n",
    "| CHAS\t| int   |是否邻近 Charles River 1=邻近；0=不邻近|\n",
    "| NOX\t| float |一氧化氮浓度  | \n",
    "| RM\t| float |每栋房屋的平均客房数 |\n",
    "| AGE\t| float |1940年之前建成的自用单位比例 |\n",
    "| DIS\t| float |到波士顿5个就业中心的加权距离 |\n",
    "| RAD\t| int   |到径向公路的可达性指数 |\n",
    "| TAX\t| int   |全值财产税率  |\n",
    "| PTRATIO|float | 学生与教师的比例 |\n",
    "| LSTAT\t| float |低收入人群占比 |\n",
    "| MEDV\t| float |同类房屋价格的中位数 |\n",
    "  \n",
    "  </center>\n",
    "  <center>表2.1 波士顿房价字段含义</center>\n",
    "  \n",
    "  预览前5条数据，代码实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>CRIM</th>\n",
       "      <th>ZN</th>\n",
       "      <th>INDUS</th>\n",
       "      <th>CHAS</th>\n",
       "      <th>NOX</th>\n",
       "      <th>RM</th>\n",
       "      <th>AGE</th>\n",
       "      <th>DIS</th>\n",
       "      <th>RAD</th>\n",
       "      <th>TAX</th>\n",
       "      <th>PTRATIO</th>\n",
       "      <th>LSTAT</th>\n",
       "      <th>MEDV</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.00632</td>\n",
       "      <td>18.0</td>\n",
       "      <td>2.31</td>\n",
       "      <td>0</td>\n",
       "      <td>0.538</td>\n",
       "      <td>6.575</td>\n",
       "      <td>65.2</td>\n",
       "      <td>4.0900</td>\n",
       "      <td>1</td>\n",
       "      <td>296</td>\n",
       "      <td>15.3</td>\n",
       "      <td>4.98</td>\n",
       "      <td>24.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.02731</td>\n",
       "      <td>0.0</td>\n",
       "      <td>7.07</td>\n",
       "      <td>0</td>\n",
       "      <td>0.469</td>\n",
       "      <td>6.421</td>\n",
       "      <td>78.9</td>\n",
       "      <td>4.9671</td>\n",
       "      <td>2</td>\n",
       "      <td>242</td>\n",
       "      <td>17.8</td>\n",
       "      <td>9.14</td>\n",
       "      <td>21.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.02729</td>\n",
       "      <td>0.0</td>\n",
       "      <td>7.07</td>\n",
       "      <td>0</td>\n",
       "      <td>0.469</td>\n",
       "      <td>7.185</td>\n",
       "      <td>61.1</td>\n",
       "      <td>4.9671</td>\n",
       "      <td>2</td>\n",
       "      <td>242</td>\n",
       "      <td>17.8</td>\n",
       "      <td>4.03</td>\n",
       "      <td>34.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.03237</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2.18</td>\n",
       "      <td>0</td>\n",
       "      <td>0.458</td>\n",
       "      <td>6.998</td>\n",
       "      <td>45.8</td>\n",
       "      <td>6.0622</td>\n",
       "      <td>3</td>\n",
       "      <td>222</td>\n",
       "      <td>18.7</td>\n",
       "      <td>2.94</td>\n",
       "      <td>33.4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.06905</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2.18</td>\n",
       "      <td>0</td>\n",
       "      <td>0.458</td>\n",
       "      <td>7.147</td>\n",
       "      <td>54.2</td>\n",
       "      <td>6.0622</td>\n",
       "      <td>3</td>\n",
       "      <td>222</td>\n",
       "      <td>18.7</td>\n",
       "      <td>5.33</td>\n",
       "      <td>36.2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      CRIM    ZN  INDUS  CHAS    NOX     RM   AGE     DIS  RAD  TAX  PTRATIO  \\\n",
       "0  0.00632  18.0   2.31     0  0.538  6.575  65.2  4.0900    1  296     15.3   \n",
       "1  0.02731   0.0   7.07     0  0.469  6.421  78.9  4.9671    2  242     17.8   \n",
       "2  0.02729   0.0   7.07     0  0.469  7.185  61.1  4.9671    2  242     17.8   \n",
       "3  0.03237   0.0   2.18     0  0.458  6.998  45.8  6.0622    3  222     18.7   \n",
       "4  0.06905   0.0   2.18     0  0.458  7.147  54.2  6.0622    3  222     18.7   \n",
       "\n",
       "   LSTAT  MEDV  \n",
       "0   4.98  24.0  \n",
       "1   9.14  21.6  \n",
       "2   4.03  34.7  \n",
       "3   2.94  33.4  \n",
       "4   5.33  36.2  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd # 开源数据分析和操作工具\n",
    "\n",
    "# 利用pandas加载波士顿房价的数据集\n",
    "data=pd.read_csv(\"/home/aistudio/work/boston_house_prices.csv\")\n",
    "# 预览前5行数据\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### 2.5.1.2  数据清洗 \n",
    "\n",
    "对数据集中的缺失值或异常值等情况进行分析和处理，保证数据可以被模型正常读取。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "* **缺失值分析**  \n",
    "\n",
    "通过`isna()`方法判断数据中各元素是否缺失，然后通过`sum()`方法统计每个字段缺失情况，代码实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "CRIM       0\n",
       "ZN         0\n",
       "INDUS      0\n",
       "CHAS       0\n",
       "NOX        0\n",
       "RM         0\n",
       "AGE        0\n",
       "DIS        0\n",
       "RAD        0\n",
       "TAX        0\n",
       "PTRATIO    0\n",
       "LSTAT      0\n",
       "MEDV       0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 查看各字段缺失值统计情况\n",
    "data.isna().sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "从输出结果看，波士顿房价预测数据集中不存在缺失值的情况。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "* **异常值处理**\n",
    "\n",
    "通过箱线图直观的显示数据分布，并观测数据中的异常值。箱线图一般由五个统计值组成：最大值、上四分位、中位数、下四分位和最小值。一般来说，观测到的数据大于最大估计值或者小于最小估计值则判断为异常值，其中\n",
    "$$\n",
    "最大估计值 = 上四分位 + 1.5 * (上四分位 - 下四分位)\\\\\n",
    "最小估计值=下四分位 - 1.5 * (上四分位 - 下四分位)\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x1500 with 13 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt # 可视化工具\n",
    "\n",
    "# 箱线图查看异常值分布\n",
    "def boxplot(data, fig_name):\n",
    "    # 绘制每个属性的箱线图\n",
    "    data_col = list(data.columns)\n",
    "    \n",
    "    # 连续画几个图片\n",
    "    plt.figure(figsize=(5, 5), dpi=300)\n",
    "    # 子图调整\n",
    "    plt.subplots_adjust(wspace=0.6)\n",
    "    # 每个特征画一个箱线图\n",
    "    for i, col_name in enumerate(data_col):\n",
    "        plt.subplot(3, 5, i+1)\n",
    "        # 画箱线图\n",
    "        plt.boxplot(data[col_name], \n",
    "                    showmeans=True, \n",
    "                    meanprops={\"markersize\":1,\"marker\":\"D\",\"markeredgecolor\":'#f19ec2'}, # 均值的属性\n",
    "                    medianprops={\"color\":'#e4007f'}, # 中位数线的属性\n",
    "                    whiskerprops={\"color\":'#e4007f', \"linewidth\":0.4, 'linestyle':\"--\"},\n",
    "                    flierprops={\"markersize\":0.4},\n",
    "                    ) \n",
    "        # 图名\n",
    "        plt.title(col_name, fontdict={\"size\":5}, pad=2)\n",
    "        # y方向刻度\n",
    "        plt.yticks(fontsize=4, rotation=90)\n",
    "        plt.tick_params(pad=0.5)\n",
    "        # x方向刻度\n",
    "        plt.xticks([])\n",
    "    plt.savefig(fig_name)\n",
    "    plt.show()\n",
    "\n",
    "boxplot(data, 'ml-vis5.pdf')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "**图2.4**是箱线图的一个示例，可对照查看具体含义。\n",
    "\n",
    "<center><img src=\"https://ai-studio-static-online.cdn.bcebos.com/242350bbd60d4afbbedc62bdc5579a54fa8e375d2481408d9be77069e578f39e\" width=700 ></img></center>\n",
    "<center>图2.4 箱线图示例</center>\n",
    "\n",
    "从输出结果看，数据中存在较多的异常值（图中上下边缘以外的空心小圆圈）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "使用四分位值筛选出箱线图中分布的异常值，并将这些数据视为噪声，其将被临界值取代，代码实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1500x1500 with 13 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 四分位处理异常值\n",
    "num_features=data.select_dtypes(exclude=['object','bool']).columns.tolist()\n",
    "\n",
    "for feature in num_features:\n",
    "    if feature =='CHAS':\n",
    "        continue\n",
    "    \n",
    "    Q1  = data[feature].quantile(q=0.25) # 下四分位\n",
    "    Q3  = data[feature].quantile(q=0.75) # 上四分位\n",
    "    \n",
    "    IQR = Q3-Q1 \n",
    "    top = Q3+1.5*IQR # 最大估计值\n",
    "    bot = Q1-1.5*IQR # 最小估计值\n",
    "    values=data[feature].values\n",
    "    values[values > top] = top # 临界值取代噪声\n",
    "    values[values < bot] = bot # 临界值取代噪声\n",
    "    data[feature] = values.astype(data[feature].dtypes)\n",
    "\n",
    "# 再次查看箱线图，异常值已被临界值替换（数据量较多或本身异常值较少时，箱线图展示会不容易体现出来）\n",
    "boxplot(data, 'ml-vis6.pdf')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "从输出结果看，经过异常值处理后，箱线图中异常值得到了改善。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### 2.5.1.3 数据集划分 \n",
    "\n",
    "由于本实验比较简单，将数据集划分为两份：训练集和测试集，不包括验证集。\n",
    "\n",
    "具体代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import paddle\n",
    "\n",
    "paddle.seed(10)\n",
    "\n",
    "# 划分训练集和测试集\n",
    "def train_test_split(X, y, train_percent=0.8):\n",
    "    n = len(X)\n",
    "    shuffled_indices = paddle.randperm(n) # 返回一个数值在0到n-1、随机排列的1-D Tensor\n",
    "    train_set_size = int(n*train_percent)\n",
    "    train_indices = shuffled_indices[:train_set_size]\n",
    "    test_indices = shuffled_indices[train_set_size:]\n",
    "\n",
    "    X = X.values\n",
    "    y = y.values\n",
    "\n",
    "    X_train=X[train_indices]\n",
    "    y_train = y[train_indices]\n",
    "    \n",
    "    X_test = X[test_indices]\n",
    "    y_test = y[test_indices]\n",
    "\n",
    "    return X_train, X_test, y_train, y_test \n",
    "\n",
    "\n",
    "X = data.drop(['MEDV'], axis=1)\n",
    "y = data['MEDV']\n",
    "\n",
    "X_train, X_test, y_train, y_test = train_test_split(X,y)# X_train每一行是个样本，shape[N,D]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### 2.5.1.4 特征工程\n",
    "为了消除纲量对数据特征之间影响，在模型训练前，需要对特征数据进行归一化处理，将数据缩放到[0, 1]区间内，使得不同特征之间具有可比性。\n",
    "\n",
    "代码实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import paddle\n",
    "\n",
    "X_train = paddle.to_tensor(X_train,dtype='float32')\n",
    "X_test = paddle.to_tensor(X_test,dtype='float32')\n",
    "y_train = paddle.to_tensor(y_train,dtype='float32')\n",
    "y_test = paddle.to_tensor(y_test,dtype='float32')\n",
    "\n",
    "X_min = paddle.min(X_train,axis=0)\n",
    "X_max = paddle.max(X_train,axis=0)\n",
    "\n",
    "X_train = (X_train-X_min)/(X_max-X_min)\n",
    "\n",
    "X_test  = (X_test-X_min)/(X_max-X_min)\n",
    "\n",
    "# 训练集构造\n",
    "train_dataset=(X_train,y_train)\n",
    "# 测试集构造\n",
    "test_dataset=(X_test,y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 2.5.2 模型构建\n",
    "\n",
    "实例化一个线性回归模型，特征维度为 12:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from nndl.op import Linear\n",
    "\n",
    "# 模型实例化\n",
    "input_size = 12\n",
    "model=Linear(input_size)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 2.5.3 完善Runner类\n",
    "模型定义好后，围绕模型需要配置损失函数、优化器、评估、测试等信息，以及模型相关的一些其他信息（如模型存储路径等）。\n",
    "\n",
    "在本章中使用的**Runner**类为V1版本。其中训练过程通过直接求解解析解的方式得到模型参数，没有模型优化及计算损失函数过程，模型训练结束后保存模型参数。\n",
    "\n",
    "训练配置中定义:\n",
    "* 训练环境，如GPU还是CPU，本案例不涉及；\n",
    "* 优化器，本案例不涉及；\n",
    "* 损失函数，本案例通过平方损失函数得到模型参数的解析解；\n",
    "* 评估指标，本案例利用MSE评估模型效果。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "在测试集上使用MSE对模型性能进行评估。本案例利用飞桨框架提供的[MSELoss API](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/MSELoss_cn.html)实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import paddle.nn as nn\n",
    "mse_loss = nn.MSELoss()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "具体实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import paddle\n",
    "import os\n",
    "from nndl.opitimizer import optimizer_lsm\n",
    "\n",
    "class Runner(object):\n",
    "    def __init__(self, model, optimizer, loss_fn, metric):\n",
    "        # 优化器和损失函数为None,不再关注\n",
    "\n",
    "        # 模型\n",
    "        self.model=model\n",
    "        # 评估指标\n",
    "        self.metric = metric\n",
    "        # 优化器\n",
    "        self.optimizer = optimizer\n",
    "    \n",
    "    def train(self,dataset,reg_lambda,model_dir):\n",
    "        X,y = dataset\n",
    "        self.optimizer(self.model,X,y,reg_lambda)\n",
    "\n",
    "        # 保存模型\n",
    "        self.save_model(model_dir)\n",
    "    \n",
    "    def evaluate(self, dataset, **kwargs):\n",
    "        X,y = dataset\n",
    "\n",
    "        y_pred = self.model(X)\n",
    "        result = self.metric(y_pred, y)\n",
    "\n",
    "        return result\n",
    "\n",
    "    def predict(self, X, **kwargs):\n",
    "        return self.model(X)\n",
    "    \n",
    "    def save_model(self, model_dir):\n",
    "        if not os.path.exists(model_dir):\n",
    "            os.makedirs(model_dir)\n",
    "        \n",
    "        params_saved_path = os.path.join(model_dir,'params.pdtensor')\n",
    "        paddle.save(model.params,params_saved_path)\n",
    "\n",
    "    def load_model(self, model_dir):\n",
    "        params_saved_path = os.path.join(model_dir,'params.pdtensor')\n",
    "        self.model.params=paddle.load(params_saved_path)\n",
    "\n",
    "optimizer = optimizer_lsm\n",
    "\n",
    "# 实例化Runner\n",
    "runner = Runner(model, optimizer=optimizer,loss_fn=None, metric=mse_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 2.5.4 模型训练\n",
    "\n",
    "在组装完成`Runner`之后，我们将开始进行模型训练、评估和测试。首先，我们先实例化`Runner`，然后开始进行装配训练环境，接下来就可以开始训练了，相关代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 模型保存文件夹\n",
    "saved_dir = '/home/aistudio/work/models'\n",
    "\n",
    "# 启动训练\n",
    "runner.train(train_dataset,reg_lambda=0,model_dir=saved_dir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "打印出训练得到的权重："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CRIM weight: -6.7268967628479\n",
      "ZN weight: 1.28081214427948\n",
      "INDUS weight: -0.4696650803089142\n",
      "CHAS weight: 2.235346794128418\n",
      "NOX weight: -7.0105814933776855\n",
      "RM weight: 9.76220417022705\n",
      "AGE weight: -0.8556219339370728\n",
      "DIS weight: -9.265738487243652\n",
      "RAD weight: 7.973038673400879\n",
      "TAX weight: -4.365403175354004\n",
      "PTRATIO weight: -7.105883598327637\n",
      "LSTAT weight: -13.165120124816895\n",
      "b: 32.12007522583008\n"
     ]
    }
   ],
   "source": [
    "columns_list = data.columns.to_list()\n",
    "weights = runner.model.params['w'].tolist()\n",
    "b = runner.model.params['b'].item()\n",
    "\n",
    "for i in range(len(weights)):\n",
    "    print(columns_list[i],\"weight:\",weights[i])\n",
    "\n",
    "print(\"b:\",b)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "从输出结果看，CRIM、PTRATIO等的权重为负数，表示该镇的人均犯罪率与房价负相关，学生与教师比例越大，房价越低。RAD和CHAS等为正，表示到径向公路的可达性指数越高，房价越高；临近Charles River房价高。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 2.5.5 模型测试\n",
    "\n",
    "加载训练好的模型参数，在测试集上得到模型的MSE指标。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MSE: 12.345974922180176\n"
     ]
    }
   ],
   "source": [
    "# 加载模型权重\n",
    "runner.load_model(saved_dir)\n",
    "\n",
    "mse = runner.evaluate(test_dataset)\n",
    "print('MSE:', mse.item())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 2.5.6 模型预测\n",
    "\n",
    "使用`Runner`中`load_model`函数加载保存好的模型，使用`predict`进行模型预测，代码实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "真实房价： 33.099998474121094\n",
      "预测的房价： 33.04654312133789\n"
     ]
    }
   ],
   "source": [
    "runner.load_model(saved_dir)\n",
    "pred = runner.predict(X_test[:1])\n",
    "print(\"真实房价：\",y_test[:1].item())\n",
    "print(\"预测的房价：\",pred.item())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "从输出结果看，预测房价接近真实房价。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "py35-paddle1.2.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
